/*
7、不同的二叉搜索树
2022-10-14
link:96-https://leetcode.cn/problems/unique-binary-search-trees/
question:
	给定一个整数 n，求以 1 ... n 为节点组成的二叉搜索树有多少种？
answer:
	1、dp[i]的定义：i的不同元素节点组成的二叉搜索树的个数为dp[i]
	2、递推公式：dp[i] += dp[j - 1] * dp[i - j]; ，j-1 为j为头结点左子树节点数量，i-j 为以j为头结点右子树节点数量
	3、dp数组的初始化：
		从递归公式上来讲，dp[以j为头结点左子树节点数量] * dp[以j为头结点右子树节点数量]
		中以j为头结点左子树节点数量为0，也需要dp[以j为头结点左子树节点数量] = 1， 否则乘法的结果就都变成0了。
		所以初始化dp[0] = 1
	4、确定遍历顺序：
		首先一定是遍历节点数，从递归公式：dp[i] += dp[j - 1] * dp[i - j]可以看出，节点数为i的状态是依靠 i之前节点数的状态。
		那么遍历i里面每一个数作为头结点的状态，用j来遍历。
	5、草稿纸：举例推到dp数组是否正确
*/

func numTrees(n int) int {
	dp := make([]int, n+1)
	// 初始化
	dp[0] = 1
	// 遍历更新
	for i := 1; i <= n; i++ {
		for j := 1; j <= i; j++ {
			dp[i] += dp[j-1] * dp[i-j] // 递推公式！关键，不是很好懂！
		}
	}
	// 返回
	return dp[n]
}